package com.example.demo;

import cn.hutool.core.text.NamingCase;
import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONObject;
import com.google.protobuf.Descriptors;
import com.google.protobuf.Message;
import io.grpc.ServiceDescriptor;

import java.io.IOException;
import java.io.InputStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class CamelToSnakeConverter {

    private static final List<String> EXCLUDE_TYPES = List.of("HeadReqVO", "HeadResVO");

    private static void processFile(Path filePath) {
        try {
            String content = new String(Files.readAllBytes(filePath));

            // 正则表达式匹配成员变量声明
            // 匹配 private/protected/public + 类型 + 变量名
            Pattern pattern = Pattern.compile(
                    "(private|protected|public)\\s+(?:static\\s+)?(?:final\\s+)?(\\w+)\\s+([a-z][a-zA-Z0-9]*)(\\s*[=;])");

            Matcher matcher = pattern.matcher(content);
            StringBuffer sb = new StringBuffer();

            while (matcher.find()) {
                String modifier = matcher.group(1);
                String camelName = matcher.group(2);
                String suffix = matcher.group(3);

                // 转换为下划线命名
                String snakeName = camelToSnake(camelName);

                // 替换原字符串
                matcher.appendReplacement(sb, modifier + " " + snakeName + suffix);
            }
            matcher.appendTail(sb);

            // 如果有修改，则写入文件
            if (!content.equals(sb.toString())) {
//                Files.write(filePath, sb.toString().getBytes());
                System.out.println(sb);
                System.out.println("Processed: " + filePath);
            }
        } catch (IOException e) {
            System.err.println("Error processing file: " + filePath);
            e.printStackTrace();
        }
    }

    private static String camelToSnake(String camel) {
        // 将驼峰转换为下划线
        String regex = "(?<=[a-z0-9])[A-Z]";
        String replacement = "_$0";
        String snake = camel.replaceAll(regex, replacement).toLowerCase();
        return snake;
    }

    public static void printAllFields(Message message, int direction) {
        String fullName = message.getDescriptorForType().getFullName();  // 包含包名的完整名称
        String simpleName = message.getDescriptorForType().getName();
        System.out.printf("@Data\n" +
                          "public class %sVO {", simpleName);
        System.out.println();
        List<Message> nested = new ArrayList<>();
        List<String> mapper = new ArrayList<>();
        for (Descriptors.FieldDescriptor field : message.getDescriptorForType().getFields()) {
            Descriptors.FieldDescriptor.Type type = field.getType();
            String typeStr = "String";
            if (type == Descriptors.FieldDescriptor.Type.MESSAGE) {
                typeStr = field.getMessageType().getName() + "VO";
            }
            if ("HeadReqVO".equals(typeStr)) {
                continue;
            }
            mapper.add(NamingCase.toCamelCase(field.getName()));
            if ("HeadResVO".equals(typeStr)) {
                continue;
            }
            System.out.printf("private %s %s; ", typeStr, NamingCase.toUnderlineCase(field.getName()));
            System.out.println();
            if (field.getType() == Descriptors.FieldDescriptor.Type.MESSAGE) {
                nested.add((Message) message.getField(field));
            }
        }
        System.out.println("}");
        if (direction == 0) {
            for (String s : mapper) {
                System.out.printf("  @Mapping(target = \"%s\", source = \"%s\")", NamingCase.toUnderlineCase(s), s);
                System.out.println();
            }
        } else {
            for (String s : mapper) {
                System.out.printf("  @Mapping(target = \"%s\", source = \"%s\")", s, NamingCase.toUnderlineCase(s));
                System.out.println();
            }
        }

        for (Message m : nested) {
            printAllFields(m, direction);
        }
    }

    public static JSONObject convertToJson(Message message) {
        JSONObject json = new JSONObject();
        try {

            for (Descriptors.FieldDescriptor field : message.getDescriptorForType().getFields()) {
                String name = NamingCase.toUnderlineCase(field.getName());
                if (field.getType() == Descriptors.FieldDescriptor.Type.MESSAGE) {
                    String typeName = field.getMessageType().getName() + "VO";
                    if (EXCLUDE_TYPES.contains(typeName)) continue;
                    if (field.isRepeated()) {
                        JSONArray array = new JSONArray();
                        for (Message item : (List<Message>) message.getField(field)) {
                            array.put(convertToJson(item));
                        }

                        json.put(name, array);
                    } else {
                        json.put(name,
                                convertToJson((Message) message.getField(field)));
                    }
                } else {
                    if (field.isRepeated()) {
                        json.put(name, new JSONArray(message.getField(field)));
                    } else {
                        json.put(name, message.getField(field));
                    }
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return json;
    }


    public static void printAllFields(Message message) {
        String simpleName = message.getDescriptorForType().getName();
        System.out.print(simpleName + " ");
        System.out.println(convertToJson(message));
    }

    public static void main(String[] args) {

        ServiceDescriptor serviceDescriptor = null;//HkScanMerchantServiceGrpc.getServiceDescriptor();

        System.out.printf("服务名称 ：%s \n", serviceDescriptor.getName());


// 遍历方法定义
        serviceDescriptor.getMethods().forEach(method -> {
            System.out.printf("服务名称 ：%s \n", method.getFullMethodName());
            Message message = (Message) method.getRequestMarshaller().parse(InputStream.nullInputStream());
            System.out.printf("请求参数：%s", convertToJson(message));
            message = (Message) method.getResponseMarshaller().parse(InputStream.nullInputStream());
            System.out.printf("响应参数：%s", convertToJson(message));
        });
    }


}